package web

import (
	"bili-server/app/cfg"
	"bili-server/app/log"
	"context"
	"embed"
	"fmt"
	"github.com/gin-gonic/gin"
	ginSwagger "github.com/swaggo/gin-swagger"
	"github.com/swaggo/gin-swagger/swaggerFiles"
	"net/http"
	"time"
)

type Response struct {
	Status bool        `json:"status"`
	Msg    string      `json:"msg,omitempty"`
	Data   interface{} `json:"data,omitempty"`
	do     string
	show   bool
}

func Success(c *gin.Context, other ...interface{}) {
	r := Response{Status: true, show: true}
	for _, v := range other {
		switch v.(type) {
		case string:
			r.Msg = v.(string)
		case bool:
			r.show = v.(bool)
		default:
			r.Data = v
		}
	}
	if r.Msg == "" {
		r.Msg = "操作"
	}
	r.Msg += "成功"
	c.JSON(http.StatusOK, r)
	log.L.Info(r.Msg)
}

func Failure(c *gin.Context, do string, other ...interface{}) {
	r := Response{Status: false}
	for _, v := range other {
		switch v.(type) {
		case string:
			r.Msg = v.(string)
		case error:
			r.Msg = v.(error).Error()
		default:
			r.Data = v
		}
	}
	do = fmt.Sprintf("%s失败", do)
	if r.Msg != "" {
		r.Msg = fmt.Sprintf("%s: %s", do, r.Msg)
	} else {
		r.Msg = do
	}
	c.JSON(http.StatusOK, r)
	log.L.Error(r.Msg)
}

type Web struct {
	server *http.Server
	www    embed.FS
}

// Run 运行Web服务
func (w *Web) Run() {
	log.L.Info("运行Web程序")

	config := cfg.GetConfig()
	engine := gin.Default()

	{
		v := new(Video)
		engine.Group("/api/videos").
			GET("", v.List).
			GET("/:id", v.Info).
			GET("/:id/danmu", v.DanMu)

	}
	//---------------------------------------------------------------------//

	for _, d := range cfg.GetConfig().Dir {
		engine.Static("videos", d)
	}
	engine.Static("js", "./www/js")
	engine.Static("css", "./www/css")
	engine.Static("favicon.ico", "./www/favicon.ico")
	engine.StaticFile("/", "./www/index.html")
	engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	w.server = &http.Server{Addr: config.WebURL, Handler: engine}
	go func() {
		log.L.Info(fmt.Sprintf("Web Server start at %s", config.WebURL))
		if err := w.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.L.Fatalf("listen: %s\n", err)
		}
	}()
}

// Shutdown 关闭服务
func (w *Web) Shutdown() {
	log.L.Info("Shutdown Web Server ...")
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	if err := w.server.Shutdown(ctx); err != nil {
		log.L.Error("Server Shutdown:", err)
	}
	select {
	case <-ctx.Done():
		log.L.Info("timeout of 1 second.")
	}
	log.L.Info("Web Server exiting")
}
